package com.itheima.service.db.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.itheima.domain.db.AnalysisByDay;
import com.itheima.domain.db.AnalysisItmes;
import com.itheima.mapper.AnalysisByDayMapper;
import com.itheima.mapper.LogMapper;
import com.itheima.service.db.AnalysisByDayService;
import com.itheima.util.ComputeUtil;
import com.itheima.vo.AnalysisSummaryVo;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@DubboService
public class AnalysisByDayServiceImpl implements AnalysisByDayService {

    @Autowired
    LogMapper logMapper;

    @Autowired
    AnalysisByDayMapper analysisByDayMapper;

    @Override
    public void saveOrUpdate() {
        //0.准备昨日和今日的日期字符串
        String today = DateUtil.offsetDay(new Date(), 0).toDateStr();
        String yesterday = DateUtil.offsetDay(new Date(), -1).toDateStr();

        //1.通过日期查询统计表中的数据
        LambdaQueryWrapper<AnalysisByDay> qw = new LambdaQueryWrapper<>();
        qw.eq(AnalysisByDay::getRecordDate,today);
        AnalysisByDay analysisByDay = analysisByDayMapper.selectOne(qw);

        //2.判断今日数据是否存在
        if (analysisByDay != null) {
            //2.1 若存在则更新
            analysisByDay.setNumRegistered(logMapper.findRegisterOrLoginCount(today,"0102"));
            analysisByDay.setNumActive(logMapper.findActiveCount(today));
            analysisByDay.setNumLogin(logMapper.findRegisterOrLoginCount(today,"0101"));
            analysisByDay.setNumRetention1d(logMapper.findRetention1d(today,yesterday));

            analysisByDayMapper.updateById(analysisByDay);
        }else{
            //2.2 若不存在则保存
            analysisByDay = new AnalysisByDay();

            analysisByDay.setRecordDate(new Date());
            analysisByDay.setNumRegistered(logMapper.findRegisterOrLoginCount(today,"0102"));
            analysisByDay.setNumActive(logMapper.findActiveCount(today));
            analysisByDay.setNumLogin(logMapper.findRegisterOrLoginCount(today,"0101"));
            analysisByDay.setNumRetention1d(logMapper.findRetention1d(today,yesterday));

            analysisByDayMapper.insert(analysisByDay);
        }

    }
    //数据统计
    @Override
    public AnalysisSummaryVo findSummary() {
        //1.准备基础数据
        Date day = new Date();
        String today = DateUtil.offsetDay(day, 0).toDateStr();
        String yesterday = DateUtil.offsetDay(day, -1).toDateStr();
        String passWeek = DateUtil.offsetDay(day, -7).toDateStr();
        String passMonth = DateUtil.offsetDay(day, -30).toDateStr();

        //准备今天的所有数据
        AnalysisByDay todayData = analysisByDayMapper.findByRecordDate(today);
        //准备昨天的所有数据
        AnalysisByDay yesterdayData = analysisByDayMapper.findByRecordDate(yesterday);

        //2.创建vo
        AnalysisSummaryVo vo = new AnalysisSummaryVo();

        //3.设置9个字段
        //累计用户数
        vo.setCumulativeUsers(analysisByDayMapper.findUserTotalCount());
        //过去30天活跃用户数
        vo.setActivePassMonth(analysisByDayMapper.findActiveUserCountInPeriod(passMonth,yesterday));
        //过去7天活跃用户
        vo.setActivePassWeek(analysisByDayMapper.findActiveUserCountInPeriod(passWeek,yesterday));
        //今日新增用户数量
        vo.setNewUsersToday(todayData.getNumRegistered().longValue());
        //今日新增用户涨跌率，单位百分数，正数为涨，负数为跌   BigDecimal : 商业数字格式
        vo.setNewUsersTodayRate(ComputeUtil.computeRate(todayData.getNumRegistered(),yesterdayData.getNumRegistered()));
        //今日登录次数
        vo.setLoginTimesToday(todayData.getNumLogin().longValue());
        //今日登录次数涨跌率，单位百分数，正数为涨，负数为跌
        vo.setLoginTimesTodayRate(ComputeUtil.computeRate(todayData.getNumLogin(),yesterdayData.getNumLogin()));
        //今日活跃用户数量
        vo.setActiveUsersToday(todayData.getNumActive().longValue());
        //今日活跃用户涨跌率，单位百分数，正数为涨，负数为跌
        vo.setActiveUsersTodayRate(ComputeUtil.computeRate(todayData.getNumActive(),yesterdayData.getNumActive()));

        //4.返回vo
        return vo;
    }

    //
    @Override
    public List<List<AnalysisItmes>> findSummaryView(Long startDate, Long endDate, String type) {
        List<List<AnalysisItmes>> list = new ArrayList<>();

        //获取今年范围日期
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String start = dateFormat.format(startDate);
        String end = dateFormat.format(endDate);
        list.add(summaryViewUtil(start, end, type));

        //获取去年的范围日期
        String year = start.substring(0, 4);
        Integer i = Integer.parseInt(year)-1;
        String lastYear = i.toString();
        String lastStart = start.replace(year, lastYear);
        String lastEnd = end.replace(year, lastYear);
        list.add(summaryViewUtil(lastStart,lastEnd,type));

        return list;
    }

    public List<AnalysisItmes> summaryViewUtil(String start,String end,String type){

        //所有的日期
        List<Date> dateList = analysisByDayMapper.findDate(start, end);
        //创建集合
        List<AnalysisItmes> itmes =new ArrayList<>();
        //遍历日期 然后进行昨天今天的查询
        for (Date day : dateList) {
            //创建传输对象
            AnalysisItmes analysisItmes = new AnalysisItmes();
            String today = DateUtil.offsetDay(day, 0).toDateStr();
            //获取数据需要的日期
            String npTitle = today.substring(8);
            String title= npTitle.replaceFirst("0", "");
            //封装ananalysisItmes的title
            analysisItmes.setTitle(title);
            //获取我们想要的每天的注册，活跃，次日残留数据
            //准备今天的所有数据
            AnalysisByDay todayData = analysisByDayMapper.findByRecordDate(today);
            switch (type){
                case "101":{
                    analysisItmes.setAmount(todayData.getNumRegistered().intValue());
                    break;
                }
                case "102":{
                    analysisItmes.setAmount(todayData.getNumActive().intValue());
                    break;
                }
                case "103":{
                    analysisItmes.setAmount(todayData.getNumRetention1d());
                    break;
                }
            }
            itmes.add(analysisItmes);
        }
        return itmes;
    }

}
